﻿using System;
using System.Collections.Generic;
using System.Text;

namespace WorkNodeFramework
{
    public class Insert:IExecuteCommand
    {
        ITable table;
        List<Column> cols = new List<Column>();
        List<object> values = new List<object>();
        bool result = false;
        internal bool ResultRequired {
            get {
                return result;
            }
        }

        public Insert(ITable table) {
            this.table = table;
        }

        internal List<Column> Columns {
            get {
                return cols;
            }
        }

        internal List<object> Values {
            get {
                return values;
            }
        }

        internal ITable Table {
            get {
                return table;
            }
        }

        public Insert Set(Column column, object value)
        {
            for(int i=0;i<cols.Count;i++)
                if (cols[i].Equals(column))
                {
                    values[i] = value;
                    return this;
                }
            
            cols.Add(column);
            values.Add(value);
            return this;
        }

        public int Execute()
        {
            ParameterIndexCollection pars = new ParameterIndexCollection();
            string cmdText = table.Provider.BuildInsertQueryStatement(this, pars);
            return table.Provider.ExecuteNonQuery(cmdText,pars.ToDbParameters(table.Provider));
        }

        public T ExecuteResult<T>()
        {
            result = true;
            ParameterIndexCollection pars = new ParameterIndexCollection();
            string cmdText = table.Provider.BuildInsertQueryStatement(this, pars);
            object val = table.Provider.ExecuteScalar(cmdText, pars.ToDbParameters(table.Provider));
            return (T)Convert.ChangeType(val, typeof(T));
        }

        public static InsertInto Into(ITable table) {
            return new InsertInto(table);
        }

        public static InsertInto Into<TEntity>() 
            where TEntity:IEntity,new()
        {
            return Into((new TEntity()).Table);
        }

        #region IExecuteCommand Members

        public ExecuteCommand BuildExecuteCommand()
        {
            ParameterIndexCollection pars = new ParameterIndexCollection();
            string cmdText = table.Provider.BuildInsertQueryStatement(this, pars);
            return new ExecuteCommand(cmdText, pars.ToDbParameters(table.Provider));
        }

        #endregion
    }

    public class InsertInto:IExecuteCommand
    {
        ITable table;
        SelectQuery select;

        internal InsertInto(ITable table) {
            this.table = table;
        }

        internal ITable Table {
            get {
                return table;
            }
        }

        internal SelectQuery SelectQuery {
            get {
                return select;
            }
        }

        public InsertInto Query(SelectQuery select)
        {
            this.select = select;
            return this;
        }

        public int Execute()
        {
            ParameterIndexCollection pars = new ParameterIndexCollection();
            string cmdText = table.Provider.BuildInsertIntoQueryStatement(this, pars);
            return table.Provider.ExecuteNonQuery(cmdText,pars.ToDbParameters(table.Provider));
        }

        #region IExecuteCommand Members

        public ExecuteCommand BuildExecuteCommand()
        {
            ParameterIndexCollection pars = new ParameterIndexCollection();
            string cmdText = table.Provider.BuildInsertIntoQueryStatement(this, pars);
            return new ExecuteCommand(cmdText, pars.ToDbParameters(table.Provider));
        }

        #endregion
    }
}
